//
//  ConstraintViewController.swift
//  ZSceneDemo
//
//  Created by 张鑫 on 2020/9/7.
//  Copyright © 2020 www.lionaitech.com. All rights reserved.
//

import UIKit

class ConstraintViewController: UIViewController, SCNSceneRendererDelegate {
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .camera, target: self, action: #selector(handMove))
        
        loadModelFile()
    }
    
    var sceneView: SCNView?
    
    func loadModelFile() {
        
        //设置摄像机架设点
        let cameraNode = SCNNode()
        cameraNode.camera = SCNCamera()
        cameraNode.position = SCNVector3(0, 0, 50)
        cameraNode.camera?.zFar = 4000
        
        
        //设置光源点
        let lightNode = SCNNode()
        lightNode.light = SCNLight()
        lightNode.light?.type = .omni
        lightNode.position = SCNVector3(0, 10, 10)
        
        //设置周围环境
        let ambientLightNode = SCNNode()
        ambientLightNode.light = SCNLight()
        ambientLightNode.light?.type = .ambient
        ambientLightNode.light?.color = UIColor.lightGray
        
        let scene = SCNScene()
        scene.rootNode.addChildNode(cameraNode)
        //        scene.rootNode.addChildNode(lightNode)
        //        scene.rootNode.addChildNode(ambientLightNode)
        
        sceneView = SCNView(frame: CGRect.zero)
        sceneView?.translatesAutoresizingMaskIntoConstraints = false
        sceneView?.scene = scene
        sceneView?.allowsCameraControl = true
        //        threeDView?.showsStatistics = true
        sceneView?.backgroundColor = UIColor.white
        view.addSubview(sceneView!)
        
        
        sceneView?.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
        sceneView?.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true
        sceneView?.rightAnchor.constraint(equalTo: view.rightAnchor).isActive = true
        sceneView?.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
        
        
        //cameraNode.constraints = lookAt()
        //transform()
        ik()
        
    }
    
    // MARK: - look at constraint
    func lookAt() -> [SCNLookAtConstraint]{
        
        let target1 = SCNNode(geometry: SCNSphere(radius: 2))
        target1.position = SCNVector3(0, 2, 0)
        target1.geometry?.materials.first?.diffuse.contents = UIColor.red
        sceneView?.scene?.rootNode.addChildNode(target1);
        
        let target2 = SCNNode(geometry: SCNSphere(radius: 2))
        target2.position = SCNVector3(0, -2, 0)
        target2.geometry?.materials.first?.diffuse.contents = UIColor.green
        sceneView?.scene?.rootNode.addChildNode(target2);
        
        let cons = SCNLookAtConstraint(target: target2)
        cons.isGimbalLockEnabled = true
        
        return [cons]
    }
    
    // MARK: - transform constraint
    func transform() {
        
        let target1 = SCNNode(geometry: SCNBox(width: 4, height: 16, length: 4, chamferRadius: 0))
        target1.name = "transform"
//        target1.position = SCNVector3(0, 2, 0)
        target1.geometry?.materials.first?.diffuse.contents = UIColor.red
        sceneView?.scene?.rootNode.addChildNode(target1);
        
        let cons = SCNTransformConstraint(inWorldSpace: true) { (node, transform) -> SCNMatrix4 in
            print("\(String(describing: node.name)) ==== \(transform)")
            print("\(SCNMatrix4MakeRotation(Float(Double.pi / 4), 2, 2, 2))")
            return transform
        }
        
        target1.constraints = [cons]
    }
    
    
    /**
     
     默认的矩阵为
     SCNMatrix4(
     m11: 1.0, m12: 0.0, m13: 0.0, m14: 0.0,
     m21: 0.0, m22: 1.0, m23: 0.0, m24: 0.0,
     m31: 0.0, m32: 0.0, m33: 1.0, m34: 0.0,
     m41: 0.0, m42: 0.0, m43: 0.0, m44: 1.0)
     
     SCNMatrix4MakeTranslation(2
     SCNMatrix4(
     m11: 1.0, m12: 0.0, m13: 0.0, m14: 0.0,
     m21: 0.0, m22: 1.0, m23: 0.0, m24: 0.0,
     m31: 0.0, m32: 0.0, m33: 1.0, m34: 0.0,
     m41: 2.0, m42: 2.0, m43: 2.0, m44: 1.0)
     
     SCNMatrix4MakeScale(0.5
     SCNMatrix4(
     m11: 0.5, m12: 0.0, m13: 0.0, m14: 0.0,
     m21: 0.0, m22: 0.5, m23: 0.0, m24: 0.0,
     m31: 0.0, m32: 0.0, m33: 0.5, m34: 0.0,
     m41: 0.0, m42: 0.0, m43: 0.0, m44: 1.0)
     
     SCNMatrix4MakeRotation(Float(Double.pi / 4), 2, 2, 2)
     SCNMatrix4(
     m11: 0.80473787, m12: 0.50587934, m13: -0.3106172, m14: 0.0,
     m21: -0.3106172, m22: 0.80473787, m23: 0.50587934, m24: 0.0,
     m31: 0.50587934, m32: -0.3106172, m33: 0.80473787, m34: 0.0,
     m41: 0.0, m42: 0.0, m43: 0.0, m44: 1.0)
     */
    
    
    // MARK: - ik constrain (反向动力学约束)
    
    var ikContrait: SCNIKConstraint?
    func ik() {
        // 添加一个重力，我们让其方向朝上
        sceneView?.delegate = self

        let ctlNode = SCNNode(geometry: SCNSphere(radius: 1))
        ctlNode.geometry?.materials.first?.diffuse.contents = UIColor.red

        let bigArmNode = SCNNode(geometry: SCNCylinder(radius: 1, height: 4))
        bigArmNode.geometry?.materials.first?.diffuse.contents = UIColor.gray
//        bigArmNode.position = SCNVector3(0, 3.5, 0)
        bigArmNode.pivot = SCNMatrix4MakeTranslation(0, -3.5, 0)

        let forearmNode = SCNNode(geometry: SCNCylinder(radius: 1, height: 4))
        forearmNode.geometry?.materials.first?.diffuse.contents = UIColor.green
        forearmNode.pivot = SCNMatrix4MakeTranslation(0, -2.5, 0)
        forearmNode.position = SCNVector3(0, 2.5, 0)
        
        let handNode = SCNNode(geometry: SCNBox(width: 2, height: 2, length: 2, chamferRadius: 0.4))
        handNode.geometry?.materials.first?.diffuse.contents = UIColor.blue
        handNode.pivot = SCNMatrix4MakeTranslation(0, -1.5, 0)
        handNode.position = SCNVector3(0, 2.5, 0)
        
        sceneView?.scene?.rootNode.addChildNode(ctlNode)
        ctlNode.addChildNode(bigArmNode)
        bigArmNode.addChildNode(forearmNode)
        forearmNode.addChildNode(handNode)

        ikContrait = SCNIKConstraint.inverseKinematicsConstraint(chainRootNode: ctlNode)
        handNode.constraints = [ikContrait!]
        
        
        
        handNode.geometry?.shaderModifiers
    }
    
    @objc func handMove() {
        SCNTransaction.begin()
        SCNTransaction.animationDuration = 0.5
        
        let x = 11 - Float(arc4random_uniform(22))
        let y = 11 - Float(arc4random_uniform(22))
        let z = 11 - Float(arc4random_uniform(22))
        ikContrait?.targetPosition = SCNVector3Make(x, y, z);
        
        SCNTransaction.commit()
    }

}
